using Demo.Framework;
using Demo.Framework.Business.Debug;
using Demo.Framework.GameObjects;
using Microsoft.Xna.Framework;
//using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace Demo
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Game
    {

        ModelManager _modelManager;

        //RenderTarget2D renderTarget;


        private readonly GraphicsDeviceManager _graphics;

        private readonly PerformanceManager _perfomanceMng;
        private readonly GraphicsManager _graphicsMng;

        private KeyboardState _lastKeybState;
        //private Polygon _polygon;
        //private Texture2D _texture;

        //private SpriteBatch spriteBatch;
        private WindMill _windMill;

        public Game1()
        {
            _graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            _perfomanceMng = new PerformanceManager(this, _graphics);
            _graphicsMng = new GraphicsManager(this, _graphics);
            



            

            //renderTarget = new RenderTarget2D(GraphicsDevice, _graphics.PreferredBackBufferWidth, _graphics.PreferredBackBufferHeight);
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            //this.IsMouseVisible = false;

            GameEngine.Instance.Create(_graphics);

            _lastKeybState = Keyboard.GetState();

            
            //_polygon = new Polygon(GraphicsDevice);
            

            _modelManager = new ModelManager(this);
            var keyboardHandler = new DebugKeyboardHandler(this);

            Components.Add(_modelManager);
            Components.Add(_perfomanceMng);
            Components.Add(_graphicsMng);
            Components.Add(keyboardHandler);

            //spriteBatch = new SpriteBatch(GraphicsDevice);

            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            _modelManager.AddModel("player", "Models//player", GameEngine.Instance.Camera.Position , true);
            
            //_modelManager.AddModel("funtan","Models//scene1_funtan");
            //_modelManager.AddModel("roof","Models//scene1_roof");
            //_modelManager.AddModel("koloni","Models//scene1_koloni");
            //_modelManager.AddModel("ground","Models//scene1_ground");
            //_modelManager.AddModel("ground1","Models//scene1_ground1");
            //_modelManager.AddModel("ped1","Models//scene1_ped1");
            //_modelManager.AddModel("ped2","Models//scene1_ped2");
            //_modelManager.AddModel("ped3","Models//scene1_ped3");
            //_modelManager.AddModel("ped4","Models//scene1_ped4");
            //_modelManager.AddModel("room1","Models//scene1_room1");
            //_modelManager.AddModel("room2","Models//scene1_room2");
            //_modelManager.AddModel("Tunel1","Models//scene1_room1_Tunel");
            //_modelManager.AddModel("Tunel2","Models//scene1_room2_Tunel");
            
            //_modelManager.AddModel("pendulum1","Models//scene1_pendulum_1");
            //_modelManager.AddModel("pendulum2","Models//scene1_pendulum_2");
            //_modelManager.AddModel("pendulum3","Models//scene1_pendulum_3");
            //_modelManager.AddModel("pendulum4","Models//scene1_pendulum_4");

            //Colones
            _modelManager.AddModel("colone1_1", "Models//scene1_colone1_1");
            _modelManager.AddModel("colone1_2", "Models//scene1_colone1_2");
            _modelManager.AddModel("colone2_1", "Models//scene1_colone2_1");
            _modelManager.AddModel("colone2_2", "Models//scene1_colone2_2");
            _modelManager.AddModel("colone3_1", "Models//scene1_colone3_1");
            _modelManager.AddModel("colone3_2", "Models//scene1_colone3_2");
            _modelManager.AddModel("colone4_1", "Models//scene1_colone4_1");
            _modelManager.AddModel("colone4_2", "Models//scene1_colone4_2");

            //Mini
            _modelManager.AddModel("mini1", "Models//scene1_mini1");
            _modelManager.AddModel("mini1_1", "Models//scene1_mini1_1");
            _modelManager.AddModel("mini2", "Models//scene1_mini2");
            _modelManager.AddModel("mini2_1", "Models//scene1_mini2_1");
            _modelManager.AddModel("mini3", "Models//scene1_mini3");
            _modelManager.AddModel("mini3_1", "Models//scene1_mini3_1");
            _modelManager.AddModel("mini4", "Models//scene1_mini4");
            _modelManager.AddModel("mini4_1", "Models//scene1_mini4_1");

            //fountane
            _modelManager.AddModel("fountaneBoard", "Models//scene1_fountaneBoard");
            _modelManager.AddModel("fountaneDno", "Models//scene1_fountaneDno");

            //room1
            _modelManager.AddModel("room1", "Models//scene1_room1");
            _modelManager.AddModel("room1_board", "Models//scene1_room1_board");
            _modelManager.AddModel("room1_dno", "Models//scene1_room1_dno");
            _modelManager.AddModel("room1_floor", "Models//scene1_room1_floor");
            _modelManager.AddModel("room1_gate", "Models//scene1_room1_gate");
            _modelManager.AddModel("room1_pod", "Models//scene1_room1_pod");
            _modelManager.AddModel("room1_roof", "Models//scene1_room1_roof");
            _modelManager.AddModel("room1_tunel", "Models//scene1_room1_tunel");
            _modelManager.AddModel("room1_tunel_floor", "Models//scene1_room1_tunel_floor");
            _modelManager.AddModel("room1_tunelRoof", "Models//scene1_room1_tunelRoof");

            //room2
            _modelManager.AddModel("room2", "Models//scene1_room2");
            _modelManager.AddModel("room2_board", "Models//scene1_room2_board");
            _modelManager.AddModel("room2_dno", "Models//scene1_room2_dno");
            _modelManager.AddModel("room2_floor", "Models//scene1_room2_floor");
            _modelManager.AddModel("room2_gate", "Models//scene1_room2_gate");
            _modelManager.AddModel("room2_pod", "Models//scene1_room2_pod");
            _modelManager.AddModel("room2_roof", "Models//scene1_room2_roof");
            _modelManager.AddModel("room2_tunel", "Models//scene1_room2_tunel");
            _modelManager.AddModel("room2_tunel_floor", "Models//scene1_room2_tunel_floor");
            _modelManager.AddModel("room2_tunelRoof", "Models//scene1_room2_tunelRoof");

            //square
            _modelManager.AddModel("square", "Models//scene1_square");
            _modelManager.AddModel("squareBoard", "Models//scene1_squareBoard");
            _modelManager.AddModel("roof", "Models//scene1_roof");

            //_windMill = new WindMill(_modelManager, new Vector3(-500, 300, -2500));

            _modelManager.LoadShaderForAllModels();
            
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            _perfomanceMng.Dispose();
            Content.Unload();
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            GameEngine.Instance.Update(gameTime);
            SetPlayerPosition();
            
            //exit
            KeyboardState keyboard = Keyboard.GetState();
            if (keyboard.IsKeyDown(Keys.Escape))
                Exit();

            if (keyboard.IsKeyDown(Keys.F1) && _lastKeybState.IsKeyUp(Keys.F1))
            {
                GameEngine.Instance.Camera.MouseControl = !GameEngine.Instance.Camera.MouseControl;
            }

            _lastKeybState = Keyboard.GetState();


            //Objects
            //_windMill.Update();

            base.Update(gameTime);
        }

        private void SetPlayerPosition()
        {
            Vector3 pos = GameEngine.Instance.Camera.Position;
            pos.Y -= 170;
            _modelManager.GetModel("player").SetPosition(pos, GameEngine.Instance.Camera.YRotation);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            

            /*GraphicsDevice.Clear(Color.CornflowerBlue);
            _graphicsMng.WireFrame.ApplyIfEnabled();

            GraphicsDevice.BlendState = BlendState.Opaque;
            DepthStencilState d = new DepthStencilState {DepthBufferEnable = true};
            GraphicsDevice.DepthStencilState = d;*/

            
            //spriteBatch.Begin();
            //spriteBatch.Draw(renderTarget, new Rectangle(0, 0, 800, 600), Color.Cyan);
            //spriteBatch.End();



            base.Draw(gameTime);
        }
    }
}
